﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using Components.Enum;
using UI.Lib;
using System.Collections;
using Components;
using Controls;
using Model;
using Model.Enum;
using UI.Lib.Factory;
using Com.Seezt.Skins;

namespace UI.ParentForm
{
    public partial class BaseMedit : BaseForm
    {
        private string _saveCallFuntion;
        protected int saveSuccessCount = 0; //新增的时候，模式是不关闭新增页面继续给用户编辑的，但是如果新增后点击关闭按钮，Main页面不会自动刷新
        private List<string> dtlNotNullCols = null; //明细中不为空的字段集合
        private List<string> dtlUnqilCols = null; //明细中不为空的字段集合
        private List<VidationModel> dtlDtpCols = null;//明细中的字段类型集合
        private string[] dtlPopCols = null; //明细中弹出框的列
        private string[] dtlPopMutiCols = null; //明细中弹出商品多选框的列
        protected bool IsAfterSaveCloseWin = true;
        protected string Key = null;
        private int gridViewHeadWidth = 0;
        private int showColumnCount = 0; //显示的列的数量
        private DataTable delData = null; //明细中删除的明细行
        protected bool isAutoSaveDelRow = true; //自动保存删除的明细行
        private object[] defaultValues = null;
        protected bool saveDtlDataToServer = true; //是否将明细数据回传到服务器
        private bool _isMouseDbClick = false; //弹出框双击可以编辑，弹出框弹出后，焦点移开的事件又会去检测一遍，所以造成重复检测

        protected int ShowColumnCount { get { return showColumnCount; } }

        /// <summary>
        /// 是否为用户关闭窗口
        /// </summary>
        private bool _isUserCloseWin = true;

        //加载完成后是否最大化的标识
        protected bool MaxStateFlag = false;

        /// <summary>
        /// 保存时候调用的方法 , 类名$方法名，方法必须返回String,参数为Hashtable
        /// </summary>
        public string SaveCallFuntion
        {
            get { return _saveCallFuntion; }
            set { _saveCallFuntion = value; }
        }

        public bool IsReload
        {
            get { return IsReloadAfterSave; }
        }

        #region 属性
        /// <summary>
        /// 是否需要加载控件设计
        /// </summary>
        protected bool isNeedControl = true;

        //保存后，是否刷新父级窗口
        protected bool IsReloadAfterSave = true;

        /// <summary>
        /// 是否允许明细控件没有数据
        /// </summary>
        protected bool allowDtlEmpty = false;

        private bool _isAutoCheck = true;

        /// <summary>
        /// 是否自动验证Table
        /// </summary>
        public bool IsAutoCheck
        {
            get { return _isAutoCheck; }
            set { _isAutoCheck = value; }
        }

        #endregion

        public BaseMedit()
        {
            InitializeComponent();
            if (!isDebug)
            {
                PageInit();//初始化方法
                InitControl();// 加载控件设计
                this.dgvDtl.WriteEditCols();
            }
        }

        public BaseMedit(string modulecode, string action)
        {
            if (!string.IsNullOrEmpty(action))
                this.Action = action;

            if (!string.IsNullOrEmpty(modulecode))
                this.ModuleCode = modulecode;

            InitializeComponent();
            PageInit();//初始化方法
            InitControl();// 加载控件设计
            this.dgvDtl.WriteEditCols();
        }

        /// <summary>
        /// 加载控件设计
        /// </summary>
        private void InitControl()
        {
            if (!isNeedControl) //不加载数据库的字段设计
            {
                this.tbSummary.Visible = false;
                return;
            }

            string page = this.GetType().FullName;

            //加载页面概要设计信息
            CommonObject obj = PageCache.GetSys5A00(page, PageControlType.SummaryCtl);
            if (obj.IsEmptyData) return; //页面未设置概要信息

            int colsize = Convert.ToInt32(obj.GetValue("colsize"));
            string text = Validation.ToString(obj.GetValue("remark"));
            this.scrollBar1.Text = string.IsNullOrEmpty(text) ? Global.SummaryHelpText : text;

            Dictionary<string, DataTable> ctls = PageCache.GetLayouts(page,
                                                        PageControlType.SummaryCtl,
                                                        PageControlType.DetailCtl
                                                    );

            if (ctls == null)
                return;

            DataTable dt = ctls[PageControlType.SummaryCtl]; //加载页面控件数据设计
            DataTable dtDtl = ctls[PageControlType.DetailCtl]; //查询明细列的设计情况

            if (null == dt || 0 == dt.Rows.Count) return;

            //加载概要
            tbSummary.DataSource = dt;
            tbSummary.AutoHeight = true;
            tbSummary.ColSize = colsize;
            tbSummary.Bind(this.Action);

            List<object> lstdefaults = new List<object>();
            //加载明细列设计
            PsDataGridViewTextBoxColumn col = null;
            PsDataGridViewCheckboxColumn checkbox = null;
            List<string> dtlpop = null;
            List<string> dtlMuti = null;
            string tp3, editMode, name, defaultValue, headerText;
            bool visible = false, isRequie = false;
            int width = 0, maxInputLength = 0;
            PsDataType coltype = PsDataType.String;
            ControlType ctltype = ControlType.Text;
            int temp = 0;

            foreach (DataRow dr in dtDtl.Rows)
            {
                ctltype = (ControlType)Convert.ToInt32(dr["controltype"]); //控件类型
                tp3 = Validation.ToString(dr["tp3"]);
                editMode = Validation.ToString(dr["editmode"]);
                name = dr["colname"].ToString();
                defaultValue = (dr["defvalue"] is DBNull) ? "" : dr["defvalue"].ToString();
                maxInputLength = (dr["maxlength"] is DBNull) ? 0 : Convert.ToInt32(dr["maxlength"]);
                coltype = (PsDataType)Convert.ToInt32(dr["coltype"]);
                headerText = dr["headcn"].ToString();
                isRequie = ("y" == dr["notnull"].ToString().ToLower());
                visible = ("n" == dr["isshow"].ToString().ToLower()); //数据库中isshow y和n刚好搞反了
                temp = Validation.ToInt(dr["columnwidth"]);
                width = visible == false ? 0 : ( //字段宽度
                        (0 == temp) ? GridViewUtil.Entity.GetHeadWidth(headerText) : temp
                    );

                string format = Validation.ToString(dr["fmt"]);
                if (string.IsNullOrEmpty(format)
                    && (coltype == PsDataType.Date || coltype == PsDataType.Date))
                {
                    format = "yyyy-MM-dd";
                }

                if (ctltype == ControlType.CheckBoxList)
                {
                    checkbox = new PsDataGridViewCheckboxColumn();
                    checkbox.Name = checkbox.DataPropertyName = name;
                    checkbox.HeaderText = headerText;
                    checkbox.EditMode = editMode;
                    checkbox.Visible = visible;
                    checkbox.DefaultValue = defaultValue;
                    checkbox.Width = checkbox.DefaultWidth = width;
                    tp3 = ShowDtlColumn(name, tp3);
                    if (!string.IsNullOrEmpty(tp3)) //tp3用来存储某字段的显示条件
                    {
                        checkbox.Visible = tp3.IndexOf(this.Action) > -1;
                    }

                    gridViewHeadWidth += width;

                    checkbox.ReadOnly = checkbox.EditMode.IndexOf(this.Action) == -1;

                    lstdefaults.Add(defaultValue); //设置默认值
                    this.dgvDtl.Columns.Add(checkbox);
                }
                else
                {
                    col = new PsDataGridViewTextBoxColumn();
                    col.Name = col.DataPropertyName = name;
                    col.ColType = coltype;
                    col.HeaderText = headerText;
                    col.IsRequie = isRequie;
                    col.EditMode = editMode;
                    col.PopKey = Validation.ToString(dr["tp2"]);
                    col.Visible = visible;
                    col.Width = col.DefaultWidth = width;
                    col.MaxInputLength = maxInputLength;
                    col.DefaultValue = defaultValue;
                    col.RefCols = Validation.ToString(dr["tp8"]).ToLower();

                    if (Global.IsNumType(col.ColType))
                        col.DefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleRight;

                    if (!string.IsNullOrEmpty(format))
                    {
                        col.DefaultCellStyle.Format = format;
                    }

                    if (col.ColType == PsDataType.Int || col.ColType == PsDataType.IntThanZero
                        || col.ColType == PsDataType.IntThanZeroOrEqualZero
                            || col.ColType == PsDataType.Num || col.ColType == PsDataType.NumThanZero
                            || col.ColType == PsDataType.NumThanZeroOrEqualZero)
                    {
                        col.DefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleRight;
                    }

                    tp3 = ShowDtlColumn(name, tp3);
                    if (!string.IsNullOrEmpty(tp3)) //tp3用来存储某字段的显示条件
                    {
                        col.Visible = tp3.IndexOf(this.Action) > -1;
                    }

                    gridViewHeadWidth += width;

                    lstdefaults.Add(col.DefaultValue); //设置默认值

                    if (col.Visible) showColumnCount++;

                    if (col.IsRequie) //保存下必填的列
                    {
                        if (dtlNotNullCols == null)
                            dtlNotNullCols = new List<string>();

                        dtlNotNullCols.Add(col.Name);
                    }
                    if ("y" == Validation.ToString(dr["tp4"]).ToLower()) //记下唯一键约束
                    {
                        if (dtlUnqilCols == null)
                            dtlUnqilCols = new List<string>();

                        dtlUnqilCols.Add(col.Name);
                    }

                    if ("y" == Validation.ToString(dr["tp8"]).ToLower())
                    {
                        if (null == dtlMuti)
                        {
                            dtlMuti = new List<string>();
                        }

                        dtlMuti.Add(col.Name);
                    }

                    if (!string.IsNullOrEmpty(col.PopKey)) //只要设置了PopKey则说明是弹出框
                    {
                        if (null == dtlpop)
                        {
                            dtlpop = new List<string>();
                        }

                        dtlpop.Add(col.Name);
                    }

                    col.ReadOnly = col.EditMode.IndexOf(this.Action) == -1;

                    //记下数据类型，方便验证

                    if (dtlDtpCols == null)
                        dtlDtpCols = new List<VidationModel>();

                    dtlDtpCols.Add(new VidationModel(col.Name, col.ColType));
                    this.dgvDtl.Columns.Add(col);
                }
            }

            if (null != dtlpop)
            {
                dtlPopCols = dtlpop.ToArray();
            }

            if (null != dtlMuti)
            {
                dtlPopMutiCols = dtlMuti.ToArray();
            }

            this.defaultValues = lstdefaults.ToArray(); //将默认值保存到全局
            this.dgvDtl.AutoGenerateColumns = false;

            if ("V" == Action || "D" == Action)
            {
                tspBtnAdd.Visible = false;
                tspBtnDel.Visible = false;
            }

            AfterLoadControl();
        }

        protected virtual string ShowDtlColumn(string colname, string showAction) { return showAction; }

        /// <summary>
        /// Medit页面生成完控件执行
        /// </summary>
        protected virtual void AfterLoadControl() { }

        #region 抽象的虚方法

        //初始化方法
        protected virtual void PageInit()
        { }

        #endregion

        private void tspBtnClose_Click(object sender, EventArgs e)
        {
            IsReloadAfterSave = saveSuccessCount > 0;
            this.Close();
        }

        protected virtual void OnCancleDelete() { }

        protected void DoSave() { tspBtnSave_Click(null, null); }

        private void tspBtnSave_Click(object sender, EventArgs e)
        {
            if ("D" == this.Action)
            {
                if (MsgBox.Show(this, "提示", "删除后将不能恢复，是否确定删除？", MessageBoxButtons.YesNo) == DialogResult.No)
                {
                    OnCancleDelete();
                    return;
                }
            }

            if (_isAutoCheck && !AutoCheck()) return; //自动验证不通过
            if (!Check()) return; //手工验证失败

            Hashtable data = this.tbSummary.GetAllValue();
            //除了表格控件中的值，也许客户端还需要保存其他的值到服务器端，如果Hashtable中的键和表格中的冲突了，以本次设置为准
            Hashtable otherdb = this.SaveOtherData();

            // 将子页面中返回的数据和表格控件中的数据合并生成jSON字符串，返回服务器处理
            string json = StringUtil.Entity.MergeToJson(true, data, otherdb);
            if (string.IsNullOrEmpty(this.SaveCallFuntion)) return;

            //提取明细控件的值
            DataTable dtldata = null;
            if (saveDtlDataToServer == true && "D" != Action) //删除的时候不回传明细数据， 虽然有点武断，但是方便点
            {
                dtldata = SetDtlSaveData();
                if (null == dtldata && !allowDtlEmpty) return; //Error
            }
            string msg = CommonHelper.Entity.SaveDtl(SaveCallFuntion, json, this.Action, dtldata, delData); //调用服务器的保存方法
            var result = ResultHelper.Parse(msg);

            AfterReturnOfSave(result);

            bool isSuccess = result.IsSuccess; // 是否保存成功
            if (!isSuccess)
            {
                MsgBox.ShowErrorMsg(this, result.Msg);
                dtldata = null; //清空明细数据
            }
            else
            {
                MsgBox.Show(this, "数据保存成功！");

                AfterSaveSuccess(result.ReturnObject);

                if (!IsAfterSaveCloseWin) //保存后如果不关闭窗口的话，则清空界面
                {
                    this.tbSummary.Clear();
                    this.tbSummary.FocusFirst();

                    this.dgvDtl.Clear();
                }
            }

            saveSuccessCount++;

            //保存后调用
            AfterSaveData(isSuccess);

            if (IsAfterSaveCloseWin && isSuccess) //保存后自动关闭窗口
            {
                IsReloadAfterSave = true;
                _isUserCloseWin = false;
                this.Close();
            }

            this.tbSummary.SaveBak();
        }

        protected virtual void AfterReturnOfSave(ResultHelper result)
        {
        }

        protected virtual void AfterSaveSuccess(Dictionary<string, object> returnData)
        {
        }

        /// <summary>
        /// 自动验证
        /// </summary>
        /// <returns></returns>
        protected bool AutoCheck()
        {
            string errmsg = this.tbSummary.CheckSelf();
            if (!string.IsNullOrEmpty(errmsg))
            {
                MsgBox.ShowErrorMsg(this, errmsg);
                return false;// 概要检测不通过，直接返回
            }

            //验证明细
            errmsg = AutoCheckGrid();
            bool isTrue = string.IsNullOrEmpty(errmsg);
            if (!isTrue)
            {
                MsgBox.ShowErrorMsg(this, errmsg);
            }
            return isTrue;
        }

        //验证Grid
        private string AutoCheckGrid()
        {
            return UI.Lib.UIValidation.ValidateGrid(this.dgvDtl, null == this.dtlNotNullCols ? null : this.dtlNotNullCols.ToArray(),
                    null == this.dtlUnqilCols ? null : this.dtlUnqilCols.ToArray(),
                    null == this.dtlDtpCols ? null : this.dtlDtpCols.ToArray());
        }

        /// <summary>
        /// 保存后调用
        /// </summary>
        /// <param name="isSuccess"></param>
        protected virtual void AfterSaveData(bool isSuccess) { }

        /// <summary>
        /// 手工验证
        /// </summary>
        /// <returns></returns>
        protected virtual bool Check() { return true; }

        /// <summary>
        /// 除了表格控件中的值，也许客户端还需要保存其他的值到服务器端，如果Hashtable中的键和表格中的冲突了，以本次设置为准
        /// </summary>
        /// <returns></returns>
        protected virtual Hashtable SaveOtherData() { return null; }

        /// <summary>
        /// 自动加载页面数据
        /// </summary>
        /// <returns></returns>
        protected virtual DataRow LoadEditData(string action, string where)
        {
            action = string.IsNullOrEmpty(action) ? "E" : action; //设置默认的Action

            DataTable data = CommonHelper.Entity.LoadEditData(this.GetType().FullName, action, "Summary", where);

            if (data == null || data.Rows.Count == 0) return null;

            this.tbSummary.Fill(data); //设置页面控件的值

            return data.Rows[0]; //可能子页面中还会有用
        }

        protected virtual DataTable LoadDtlData(string action, string where)
        {
            action = string.IsNullOrEmpty(action) ? "E" : action; //设置默认的Action

            DataTable data = CommonHelper.Entity.LoadEditData(this.GetType().FullName, action, "Detail", where);

            if (data == null || data.Rows.Count == 0) return null;

            BindEditData(data);

            return data; //可能子页面中还会有用
        }

        protected void BindEditData(DataTable data)
        {
            DataGridViewRow dgr = null;
            foreach (DataRow dr in data.Rows)
            {
                dgr = new DataGridViewRow();
                dgr.CreateCells(this.dgvDtl);

                dgvDtl.Rows.Add(dgr);
                //填充值
                UIHelper.FillDataGridViewRowFromDataRow(dr, dgvDtl.Rows[dgvDtl.Rows.Count - 1]);
            }
        }

        /// <summary>
        /// 提取明细控件的值
        /// </summary>
        protected virtual DataTable SetDtlSaveData()
        {
            int rowCount = this.dgvDtl.Rows.Count;
            if (!allowDtlEmpty && 0 == rowCount)
            {
                MessageBox.Show("明细数据为空，不能保存！", "提示");
                return null;
            }

            this.dgvDtl.EndEdit();
            DataTable dt = new DataTable();
            dt.TableName = "DTLDATA";
            DataColumn dc;
            for (int i = 0; i < dgvDtl.Columns.Count; i++)
            {
                dc = new DataColumn();
                dc.ColumnName = dgvDtl.Columns[i].Name.ToString();
                dt.Columns.Add(dc);
            }
            for (int j = 0; j < dgvDtl.Rows.Count; j++)
            {
                DataRow dr = dt.NewRow();
                for (int x = 0; x < dgvDtl.Columns.Count; x++)
                {
                    dr[x] = dgvDtl.Rows[j].Cells[x].Value;
                }

                AfterRowExData(dr);//行提取值后调用
                dt.Rows.Add(dr);
            }

            return dt;
        }

        //新增明细
        private void tspBtnAdd_Click(object sender, EventArgs e)
        {
            this.dgvDtl.EndEdit(); //先结束编辑

            if (!BeforeAdd()) return; //新增时候检测

            if (this.dgvDtl.Rows.Count == 0) //第一次单击新增行时，需要对概要进行检测
            {
                string errmsg = this.tbSummary.CheckSelf();
                if (!string.IsNullOrEmpty(errmsg))// 概要检测不通过，直接返回
                {
                    MessageBox.Show(errmsg, "提示");
                    return;
                }
            }

            string msg = this.AutoCheckGrid();
            if (!String.IsNullOrEmpty(msg)) //明细检测不通过
            {
                MessageBox.Show(msg, "提示");
                return;
            }

            DataGridViewRow dr = new DataGridViewRow();
            dr.CreateCells(this.dgvDtl, defaultValues);
            dgvDtl.Rows.Add(dr);

            dgvDtl.Focus(dgvDtl.Rows.Count - 1, 0);//选择新行
            this.AfterAddRow();
        }

        //删除明细
        private void tspBtnDel_Click(object sender, EventArgs e)
        {
            if (null == this.dgvDtl.SelectedCells || 0 == this.dgvDtl.SelectedCells.Count)
                return;

            int rowindex = this.dgvDtl.SelectedCells[0].RowIndex;
            if (rowindex < 0) return;

            if (!BeforeDelete(rowindex)) return;

            if (MessageBox.Show("确定删除？", "提示", MessageBoxButtons.OKCancel) != DialogResult.OK)
                return;

            //记录删除的明细行
            if (this.isAutoSaveDelRow && "A" != this.Action)
            {
                DataGridViewRow delRow = this.dgvDtl.Rows[rowindex];

                if (delRow.IsNewRow) return;

                if (null == delData)
                {
                    delData = new DataTable();
                    delData.TableName = "DELDATA";
                    DataColumn dc;
                    for (int i = 0; i < dgvDtl.Columns.Count; i++)
                    {
                        dc = new DataColumn();
                        dc.ColumnName = dgvDtl.Columns[i].Name.ToString();
                        delData.Columns.Add(dc);
                    }
                }

                DataRow dr = delData.NewRow();
                for (int x = 0; x < delData.Columns.Count; x++)
                {
                    dr[x] = delRow.Cells[x].Value;
                }

                delData.Rows.Add(dr);

            }

            this.dgvDtl.Rows.RemoveAt(rowindex);

            this.AfterDelete();
        }

        /// <summary>
        /// 删除明细时触发
        /// </summary>
        /// <returns>是否删除</returns>
        protected virtual bool BeforeDelete(int rowIndex) { return true; }

        /// <summary>
        /// 新增明细时触发
        /// </summary>
        /// <returns>是否新增</returns>
        protected virtual bool BeforeAdd() { return true; }

        /// <summary>
        /// 新增行后触发
        /// </summary>
        protected virtual void AfterAddRow() { }

        /// <summary>
        /// 删除行后触发
        /// </summary>
        protected virtual void AfterDelete() { }

        /// <summary>
        /// 当行赋值完成后调用
        /// </summary>
        /// <param name="dr"></param>
        protected virtual void AfterRowExData(DataRow dr) { }

        /// <summary>
        /// 创建完控件后执行（添加属性）
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        protected virtual void tbSummary_AfterCreateControl(object sender, Controls.Args.SummaryArgs e)
        {
            Control c = sender as Control;
            if (c == null) return;

            //添加默认事件
            AddEvent(c);

            AfterCreateSummaryControl(c.Name, c);
        }

        protected override bool AfterPressEnterOnSummary(string ctlName)
        {
            //如果当前的控件是最后一个可见的控件Name,用于Medit页面最后一个控件上敲回车时，焦点进入明细控件
            if (ctlName == this.tbSummary.LastVisiableColomn)
            {
                if (this.tspDtlTop.Visible == true && this.tspDtlTop.Items.Count > 0 && this.tspDtlTop.Items[0] is ToolStripButton)
                {
                    ((ToolStripButton)this.tspDtlTop.Items[0]).PerformClick(); //模拟点击工具栏
                    //this.dgvDtl.Focus(0, 0);
                }
                else if (this.dgvDtl.Visible == true && this.dgvDtl.Rows.Count > 0)
                {
                    this.dgvDtl.Focus(0, 0);
                }

                return false;
            }

            //继续执行转跳TAB
            return true;
        }

        protected virtual void AfterCreateSummaryControl(string name, Control c)
        {
        }

        //Grid 敲回车自动转换到下一行
        protected void dgvDtl_KeyUp(object sender, KeyEventArgs e)
        {
            if (this.dgvDtl.IsPressDataGridView && e.KeyCode == System.Windows.Forms.Keys.Enter && _isMouseDbClick == false)
            {
                e.Handled = true;

                //如果当前列是该行的最后一列，则自动新增明细
                if (this.dgvDtl.CanEdit && this.dgvDtl.SelectedCells.Count == 1
                    && this.dgvDtl.SelectedCells[0].ColumnIndex == this.dgvDtl.LastCanEditIndex
                    && this.tspBtnAdd.Visible == true)
                {
                    if (this.dgvDtl.SelectedCells[0].RowIndex == this.dgvDtl.Rows.Count - 1)
                    {
                        tspBtnAdd_Click(null, null);
                    }
                    else //不是最后一行，那么转跳到下一个行的第一个单元格
                    {
                        System.Windows.Forms.SendKeys.Send("{TAB}");
                    }
                }
                else //否则做Tab
                {
                    string nextColName = this.dgvDtl.GetNextCanEditColomun();
                    if (string.IsNullOrEmpty(nextColName)) //找不到的情况
                    {
                        System.Windows.Forms.SendKeys.Send("{TAB}");
                    }
                    else
                    {
                        this.dgvDtl.Focus(nextColName);
                    }
                }
            }

            base.OnKeyUp(e);
        }

        /// <summary>
        /// 页面加载完成后，自动重置一次控件状态
        /// </summary>
        /// <param name="e"></param>
        protected override void OnLoad(EventArgs e)
        {
            base.OnLoad(e);

            if ("V" == this.Action) //显示状态下不显示保存按钮
            {
                tspSave.Visible = false;
            }

            if (MaxStateFlag)
            {
                this.Location = new Point(25, 15);
                this.Size = new Size(SystemInformation.WorkingArea.Width - 50, SystemInformation.WorkingArea.Height - 50);
            }

            this.RefreshControl();
            AfterSystemChangeControlState();
            this.tbSummary.FormatStyle();
            this.ResetSize();

            this.tbSummary.SaveBak(); //保存当前数据，用于做是否修改的提示

            _SetFontSize();
            _SetToolBtnStyle();
            isLoadOk = true;
        }

        /// <summary>
        /// 当页面上系统设置完控件状态后执行
        /// </summary>
        protected virtual void AfterSystemChangeControlState() { }

        /// <summary>
        /// 根据当前状态，充值页面控件状态
        /// </summary>
        protected virtual void RefreshControl()
        {
            this.tbSummary.SetControlState(this.Action);
        }

        /// <summary>
        /// 根据概要的高度，重置明细的高度
        /// </summary>
        protected virtual void ResetSize()
        {
            int summaryHeight = this.tbSummary.Height;
            summaryHeight = Math.Max(summaryHeight, 60);
            this.tbSummary.Size = new Size(this.ClientSize.Width - 40, summaryHeight);
            int winHeight = this.Height;

            this.panDtl.Location = new Point(this.panDtl.Location.X, tspTop.Height + summaryHeight + 50);
            this.panDtl.Size = new Size(this.tbSummary.Width, winHeight - summaryHeight - tspTop.Height - this.scrollBar1.Height - 90);
        }

        protected override void AfterSummaryPopUp(PsPopWin popTarget, Hashtable hs, bool clearFlag, string status)
        {
            if (null == hs || 0 == hs.Count) return;

            Table targetTable = popTarget.Parent as Table;
            Control c = null;
            PsPopWin pop = null;
            string key = "";
            string value = "";
            bool isAlert = false;
            foreach (DictionaryEntry entry in hs)
            {
                key = entry.Key.ToString();
                value = (null == entry.Value || clearFlag) ? "" : entry.Value.ToString();
                if (key == "$SELF$")
                {
                    popTarget.Text = popTarget.Value = value;
                    if (!string.IsNullOrEmpty(value))
                    {
                        popTarget.PressWord = null;
                    }
                    if (!clearFlag && string.IsNullOrEmpty(value))
                    {
                        isAlert = true; //给出提示
                    }
                }
                else if (key.IndexOf("$VALUE$") > -1)//准备将值写入弹出框份额Value内
                {
                    if (key.IndexOf("&") > -1)//准备将值写入其他弹出框份额Value内
                    {
                        string name = key.Replace("$VALUE$&", "");
                        if (!targetTable.Controls.ContainsKey(name)) continue;

                        pop = targetTable.Controls[name] as PsPopWin;
                        if (pop == c) continue;

                        pop.Value = value;
                    }
                    else
                    {
                        popTarget.Value = value;
                    }
                }
                else
                {
                    targetTable.SetValue(key, value);
                }
            }

            if (isAlert && "M" != status)
            {
                popwin_MouseDoubleClick(popTarget, null);
                //MessageBox.Show(string.Format("[{0}]未选择有效的值！", popTarget.Lable), "提示");
            }
        }

        /// <summary>
        /// 完成明细弹出框的操作
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void dgvDtl_CellMouseDoubleClick(object sender, DataGridViewCellMouseEventArgs e)
        {
            if (e.RowIndex < 0) return;

            //弹出材料编码选择框
            string colName = this.dgvDtl.Columns[e.ColumnIndex].Name; //得到列名
            if (this.dgvDtl.Columns[e.ColumnIndex].ReadOnly == true) return;

            DataGridViewRow dr = this.dgvDtl.Rows[e.RowIndex];
            string where = "";
            Hashtable hsWhere = null;
            if (null != dtlPopCols) //准备做弹出框操作
            {
                if (Array.IndexOf(dtlPopCols, colName) > -1)
                {
                    string[] others = null;
                    where = "";
                    hsWhere = null;
                    //弹出框的弹出Key
                    string popKey = ((PsDataGridViewTextBoxColumn)this.dgvDtl.Columns[e.ColumnIndex]).PopKey;
                    //弹出窗弹开之前执行
                    bool flag = this.BeforeDtlPopUp(colName, ref where, ref others);
                    if (!flag) return;

                    hsWhere = new Hashtable();
                    if (!string.IsNullOrEmpty(where))
                    {
                        hsWhere["strwhere"] = where;
                    }

                    if (null != others && 0 != others.Length) //可能设置了其他条件
                    {
                        //条件设置的顺序分别如下 table | showfields | reffield 
                        if (others.Length > 0 && null != others[0]) hsWhere["table"] = others[0];
                        if (others.Length > 1 && null != others[1]) hsWhere["showfields"] = others[1];
                        if (others.Length > 2 && null != others[2]) hsWhere["reffield"] = others[2];
                    }

                    string searchWord = sender is string ? sender.ToString() : "";
                    _isMouseDbClick = true;

                    if (null != dtlPopMutiCols && Array.IndexOf(dtlPopMutiCols, colName) > -1) //多选商品框
                    {
                        UI.CommonForm.FrmProductSelect frm = new UI.CommonForm.FrmProductSelect(popKey, hsWhere, searchWord);
                        frm.IsMutiSelect = true;
                        frm.Location = new Point(100, 100);
                        frm.ShowDialog();
                        if (!frm.IsSelected)
                        {
                            _isMouseDbClick = false;
                            return; //未选中
                        }

                        List<Hashtable> tbList = frm.GetSelectedData();
                        if (null == tbList) return;
                        bool isCurrentRow = true;
                        DataGridViewRow grow = null;
                        foreach (Hashtable tb in tbList)
                        {
                            grow = null;

                            if (isCurrentRow)
                            {
                                grow = dr;
                            }
                            else
                            {
                                grow = AddRow(); //添加新行
                            }

                            if (grow == null) return;

                            PopHelp.AfterGridPopWin(grow, colName, tb, "S");

                            AfterDtlPopWin(colName, tb, false);
                            this.dgvDtl.EndEdit();

                            isCurrentRow = false;
                        }

                        _isMouseDbClick = false;

                        string nextColName = this.dgvDtl.GetNextCanEditColomun(colName);
                        if (string.IsNullOrEmpty(nextColName)) return;
                        {
                            this.dgvDtl.Focus(nextColName);
                        }
                    }
                    else
                    {
                        FrmPopWin win = new FrmPopWin(popKey, hsWhere, searchWord);
                        win.StartPosition = FormStartPosition.CenterParent;
                        win.ShowDialog();
                        if (!win.IsSelected)
                        {
                            _isMouseDbClick = false;
                            return; //未选中
                        }

                        Hashtable hs = win.GetSelectedData();
                        PopHelp.AfterGridPopWin(dr, colName, hs, "S");

                        AfterDtlPopWin(colName, hs, false);
                        this.dgvDtl.EndEdit();
                        _isMouseDbClick = false;

                        //如果是用键盘按Enter关闭的弹出窗口的话，那么会触发DataGridView的KeyUp,则自动会跳到下一个单元格
                        if (win.SelectedType == WinOperate.Mouse)
                        {
                            string nextColName = this.dgvDtl.GetNextCanEditColomun(colName);
                            if (string.IsNullOrEmpty(nextColName)) return;
                            {
                                this.dgvDtl.Focus(nextColName);
                            }
                        }
                    }
                }
            }
        }

        private DataGridViewRow AddRow()
        {
            if (!CanClickButton(this.tspBtnAdd)) return null;

            DataGridViewRow dr = new DataGridViewRow();
            dr.CreateCells(this.dgvDtl, defaultValues);
            dgvDtl.Rows.Add(dr);

            dgvDtl.Focus(dgvDtl.Rows.Count - 1, 0);//选择新行
            this.AfterAddRow();

            return dgvDtl.Rows[dgvDtl.Rows.Count - 1];
        }

        //用户完成明细中的弹出框口手工输入后，自动带出相关列描述
        private void dgvDtl_CellEndEdit(object sender, DataGridViewCellEventArgs e)
        {
            //可能用户不想用弹出窗口选择，直接用手工输入，咱们也是要把相关的列描述给查询出来的
            if (e.RowIndex < 0) return;

            string colName = this.dgvDtl.Columns[e.ColumnIndex].Name; //得到列名
            DataGridViewRow dr = this.dgvDtl.Rows[e.RowIndex];
            DataGridViewCell dc = dr.Cells[colName];
            string where = "";
            Hashtable hsWhere = null;
            string beforeVale = string.Empty;

            if (null != dtlPopCols) //准备做弹出框操作
            {
                if (Array.IndexOf(dtlPopCols, colName) > -1 && !_isMouseDbClick)
                {
                    string[] others = null;
                    where = "";
                    hsWhere = null;

                    string popKey = ((PsDataGridViewTextBoxColumn)this.dgvDtl.Columns[e.ColumnIndex]).PopKey;

                    //弹出窗弹开之前执行 
                    bool flag = this.BeforeDtlPopUp(colName, ref where, ref others);
                    if (!flag) return;

                    hsWhere = new Hashtable();
                    if (!string.IsNullOrEmpty(where))
                    {
                        hsWhere["strwhere"] = where;
                    }
                    if (null != others && 0 != others.Length) //可能设置了其他条件
                    {
                        //条件设置的顺序分别如下 table | showfields | reffield 
                        if (others.Length > 0 && null != others[0]) hsWhere["table"] = others[0];
                        if (others.Length > 1 && null != others[1]) hsWhere["showfields"] = others[1];
                        if (others.Length > 2 && null != others[2]) hsWhere["reffield"] = others[2];
                    }

                    beforeVale = Validation.ToString(dc.Value);

                    PopService pservice = new PopService(popKey, hsWhere, beforeVale);
                    Hashtable hs = pservice.GetSelectedData();

                    bool isEmpty = Validation.IsNull(dc.Value);
                    if (isEmpty) //空值时，仅需要清空文本框
                    {
                        PopHelp.AfterGridPopWin(this.dgvDtl.Rows[e.RowIndex], colName, hs, true, "N");
                        return;
                    }
                    else
                    {
                        PopHelp.AfterGridPopWin(this.dgvDtl.Rows[e.RowIndex], colName, hs, pservice.SearchState);

                        _isMouseDbClick = false; //设置模拟鼠标双击属性为false

                        if (Validation.IsNull(this.dgvDtl.Rows[e.RowIndex].Cells[colName].Value))
                        {
                            _isMouseDbClick = true;
                            dgvDtl_CellMouseDoubleClick(beforeVale,
                                new DataGridViewCellMouseEventArgs(e.ColumnIndex, e.RowIndex, 0, 0,
                                    new MouseEventArgs(MouseButtons.Left, 2, 0, 0, 0)));
                        }

                        AfterDtlPopWin(colName, hs, false);
                    }
                }
            }

            AfterGridEndEdit(colName, e);
        }

        protected virtual void AfterGridEndEdit(string colName, DataGridViewCellEventArgs e) { }

        protected virtual bool BeforeDtlPopUp(string name, ref string where, ref string[] others)
        {
            where = "";
            others = null;
            return true;
        }

        public virtual void AfterDtlPopWin(string name, Hashtable data, bool ischange)
        { }

        #region 热键相关

        private void Form_Activated(object sender, EventArgs e)
        {
        }

        private void Form_Leave(object sender, EventArgs e)
        {
        }

        #endregion

        protected void BaseMain_ClientSizeChanged(object sender, EventArgs e)
        {
            //如果单元格的宽度之和小于我的GridView的宽度，则自动填充满
            this.dgvDtl.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.None;
            //(gridViewHeadWidth < this.dgvDtl.ClientSize.Width) ? DataGridViewAutoSizeColumnsMode.Fill :
            //     DataGridViewAutoSizeColumnsMode.None;

            ResetColumnWidth();

            AutoSize();
        }

        protected void BaseMain_Shown(object sender, EventArgs e)
        {
            BaseMain_ClientSizeChanged(sender, e);
        }

        protected virtual void AutoSize() { }

        private void dgvDtl_CellValueChanged(object sender, DataGridViewCellEventArgs e)
        {
            if (base.isLoadOk)
            {
                AfterDtlValueChanged(this.dgvDtl.Columns[e.ColumnIndex].Name, this.dgvDtl[e.ColumnIndex, e.RowIndex].Value);
            }
        }

        /// <summary>
        /// 值改变后触发
        /// </summary>
        /// <param name="name"></param>
        /// <param name="value"></param>
        protected virtual void AfterDtlValueChanged(string name, object value) { }

        private void dgvDtl_EditingControlShowing(object sender, DataGridViewEditingControlShowingEventArgs e)
        {
            string editColumnName = this.dgvDtl.Columns[this.dgvDtl.CurrentCell.ColumnIndex].Name; //当前编辑行的列名

            if (null != dtlPopCols) //准备做弹出框操作
            {
                if (Array.IndexOf(dtlPopCols, editColumnName) > -1)
                {
                    DataGridViewTextBoxEditingControl c = e.Control as DataGridViewTextBoxEditingControl;
                    c.Tag = new int[] { this.dgvDtl.CurrentCell.ColumnIndex, this.dgvDtl.CurrentRow.Index };
                    c.KeyDown -= new KeyEventHandler(c_KeyDown);
                    c.KeyDown += new KeyEventHandler(c_KeyDown);
                }
            }

            OnEditingControlShowing(editColumnName, e.Control);
        }

        //明细框中弹出框按F1键相应时间
        void c_KeyDown(object sender, KeyEventArgs e)
        {
            if (e.KeyCode == Keys.F1)
            {
                DataGridViewTextBoxEditingControl c = sender as DataGridViewTextBoxEditingControl;
                if (c == null) return;

                int[] indexs = (int[])c.Tag;
                //模拟弹出框双击事件
                dgvDtl_CellMouseDoubleClick(null, new DataGridViewCellMouseEventArgs(indexs[0], indexs[1], 0, 0
                    , new MouseEventArgs(MouseButtons.Left, 2, 0, 0, 0)));
            }
        }

        /// <summary>
        /// 当明细中的编辑控件打开时触发
        /// </summary>
        protected virtual void OnEditingControlShowing(string colName, Control c) { }

        void _SetFontSize()
        {
            this.AutoScaleMode = AutoScaleMode.None;

            this.tbSummary.Font = this.tspTop.Font
                = this.dgvDtl.Font = this.tspDtlTop.Font = Global.AllFont;

            this.dgvDtl.ColumnHeadersDefaultCellStyle.Font = Global.AllFont;
            this.dgvDtl.RowsDefaultCellStyle.Font = Global.AllFont;
        }

        private void BaseMedit_FormClosing(object sender, FormClosingEventArgs e)
        {
            bool isExit = null != Context.GetValueByKey("EXIT");

            if (!isExit)
            {
                if (_isUserCloseWin && this.tbSummary.IsModify() &&
        MessageBox.Show("界面数据已经改变，是否真要退出？", "提示", MessageBoxButtons.YesNo)
            != DialogResult.Yes)
                {
                    e.Cancel = true;
                }

                IsReloadAfterSave = saveSuccessCount > 0;
            }
        }

        private void BaseMedit_KeyDown(object sender, KeyEventArgs e)
        {
            switch (e.KeyCode)
            {
                case Keys.F8:    //按下的是F8
                    if (CanClickButton(this.tspSave)) tspBtnSave_Click(this.tspSave, null);
                    break;
                case Keys.PageUp:    //按下的是page up，Id号为106 == 返回及关闭
                    this.Close();
                    break;
                case Keys.F4:    //按下的是F4，Id号为107 == 返回及关闭
                    this.Close();
                    break;
                case Keys.F5:    //按下的是F5，Id号为108 == 调用子菜单
                    break;
            }

            FormKeyDown(e);
        }

        protected virtual void FormKeyDown(KeyEventArgs e) { }

        private void scrollBar1_Enter(object sender, EventArgs e)
        {
            SendKeys.Send("{TAB}"); //让滚动栏不获得焦点
        }

        private void dgvDtl_KeyDown(object sender, KeyEventArgs e)
        {
            //选中的单元格个数
            int selectedCellCount = this.dgvDtl.SelectedCells.Count;
            //未打开编辑器的情况下，支持F1打开弹出窗口
            if (1 == selectedCellCount && e.KeyCode == Keys.F1)
            {
                this.dgvDtl.IsPressDataGridView = false;
                DataGridViewCell dc = this.dgvDtl.SelectedCells[0];
                //模拟弹出框双击事件
                dgvDtl_CellMouseDoubleClick(null, new DataGridViewCellMouseEventArgs(dc.ColumnIndex, dc.RowIndex, 0, 0
                    , new MouseEventArgs(MouseButtons.Left, 2, 0, 0, 0)));
            }
        }

        /// <summary>
        /// 充值GridView的宽度
        /// </summary>
        void ResetColumnWidth()
        {
            if (this.dgvDtl.AutoSizeColumnsMode == DataGridViewAutoSizeColumnsMode.None)
            {
                foreach (DataGridViewColumn dc in this.dgvDtl.Columns)
                {
                    if (dc is PsDataGridViewTextBoxColumn)
                    {
                        dc.Width = ((PsDataGridViewTextBoxColumn)dc).DefaultWidth;
                    }
                    else if (dc is PsDataGridViewCheckboxColumn)
                    {
                        dc.Width = ((PsDataGridViewCheckboxColumn)dc).DefaultWidth;
                    }
                }
            }
        }

        void _SetToolBtnStyle()
        {
            ToolStripButton btn = null;
            foreach (ToolStripItem item in this.tspTop.Items)
            {
                if (item is ToolStripButton)
                {
                    btn = item as ToolStripButton;
                    btn.BackgroundImage = base.Imgs.Images[3];
                }
            }
        }
    }
}
